package com.xunqi.weixinpar.controller.alipay;

import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppMergePayModel;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.xunqi.weixinpar.config.AlipayConfig;
import com.xunqi.weixinpar.entity.Order;
import com.xunqi.weixinpar.service.OrderService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Controller
@RequestMapping(value = "/AliPay")
public class AliPayController {

    @Resource
    private OrderService orderService;

    @RequestMapping()
    @ResponseBody
    public String aliPay(HttpServletRequest request, HttpServletResponse response,String orderNO){
        try{
            //获得初始化的aliPayClient
            AlipayClient alipayClient=new DefaultAlipayClient(AlipayConfig.gatewayUrl,AlipayConfig.app_id,AlipayConfig.merchant_private_key,"json","utf-8",null,AlipayConfig.sign_type);

            //设置请求参数
            AlipayTradePagePayRequest alipayRequest=new AlipayTradePagePayRequest();
            alipayRequest.setReturnUrl(AlipayConfig.return_url);
            alipayRequest.setNotifyUrl(AlipayConfig.notify_url);

            Order order=orderService.findByOrderNo(orderNO);
            alipayRequest.setBizContent("{\"out_trade_no\":\""+ order.getOrderNO() +"\","
                    + "\"total_amount\":\""+ order.getAmount() +"\","
                    + "\"subject\":\""+ order.getSubject() +"\","
                    + "\"body\":\""+ order.getBody() +"\","
                    + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

            //请求
            String result=alipayClient.pageExecute(alipayRequest).getBody();
            //输出
            System.out.println(result);
            return result;
        }catch (Exception e){
            e.printStackTrace();
            return "error";
        }
    }

    @RequestMapping(value = "/ReturnUrl")
    public String returnUrl(HttpServletRequest request, HttpServletResponse response) throws IOException {
        PrintWriter out = response.getWriter();
        //获取支付宝get过来的反馈信息
        Map<String,String> params=new HashMap<>();
        Map<String,String[]> requestParams=request.getParameterMap();
        for (Iterator<String> iter=requestParams.keySet().iterator();iter.hasNext();){
            String name=(String)iter.next();
            String[] values=(String[])requestParams.get(name);
            String valueStr="";
            for (int i=0;i<values.length;i++){
                valueStr=(i==values.length-1)?valueStr+values[i]:valueStr+values[i]+",";
            }
            System.out.println(valueStr);
            params.put(name,valueStr);
        }

        try {
            //调用SDK验证签名
            boolean signVerified=AlipaySignature.rsaCheckV1(params,AlipayConfig.alipay_public_key,AlipayConfig.charset,AlipayConfig.sign_type);

            //请在这里编写宁的程序
            if (signVerified){
                //商户订单号
                String out_trade_no=new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");

                //支付宝交易号
                String trade_no=new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");

                //付款金额
                String total_amount=new String(request.getParameter("total_amount").getBytes("ISO-8859-1"),"UTF-8");

                return "redirect:/order/success?orderNO="+out_trade_no;
            }else{
                out.print("验签失败");
                return "404";
            }
            //——请在这里编写您的程序（以上代码仅作参考）——
        }catch (Exception e){
            e.printStackTrace();
            return "404";
        }

    }

    @RequestMapping(value = "/NotifyUrl")
    @ResponseBody
    public String notifyUrl(HttpServletRequest request, HttpServletResponse response){
        //收货支付宝post来反馈信息
        Map<String,String> params=new HashMap<>();
        Map<String,String[]> requestParams=request.getParameterMap();
        for (Iterator<String> iter=requestParams.keySet().iterator();iter.hasNext();){
            String name=(String)iter.next();
            String[] values=(String[])requestParams.get(name);
            String valueStr="";
            for (int i=0;i<values.length;i++){
                valueStr=(i==values.length-1)?valueStr+values[i]:valueStr+values[i]+",";
            }
            System.out.println(valueStr);
            params.put(name,valueStr);
        }

        try{
            //调用sdk验证签名
            boolean signVerfied=AlipaySignature.rsaCheckV1(params,AlipayConfig.alipay_public_key,AlipayConfig.charset,AlipayConfig.sign_type);

            /* 实际验证过程建议商户务必添加以下校验：
			1、需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号，
			2、判断total_amount是否确实为该订单的实际金额（即商户订单创建时的金额），
			3、校验通知中的seller_id（或者seller_email) 是否为out_trade_no这笔单据的对应的操作方（有的时候，一个商户可能有多个seller_id/seller_email）
			4、验证app_id是否为该商户本身。
			*/
            if (signVerfied){   //验证成功
                //商户订单号
                String out_trade_no=request.getParameter("out_trade_no");
                //支付宝交易号
                String trade_no=request.getParameter("trade_no");
                //交易状态
                String trade_status=request.getParameter("trade_status");

                if(trade_status.equals("TRADE_FINISHED")){
                    //判断该笔订单是否在商户网站中已经做过处理
                    //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                    //如果有做过处理，不执行商户的业务程序

                    //注意：
                    //退款日期超过可退款期限后（如三个月可退款），支付宝系统发送该交易状态通知
                }else if (trade_status.equals("TRADE_SUCCESS")){
                    //判断该笔订单是否在商户网站中已经做过处理
                    //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                    //如果有做过处理，不执行商户的业务程序
                    Order order = orderService.findByOrderNo(out_trade_no);
                    if (order!=null && order.getStatus()==0) {
                        order.setPayType(1);
                        order.setStatus(1);
                        order.setTrade_no(trade_no);
                        orderService.updateStatus(order);
                    }

                    //注意：
                    //付款完成后，支付宝系统发送该交易状态通知
                }

                return "success";
            }else{      //验证失败
                return "fail";

            }
        }catch (Exception e){
            e.printStackTrace();
            return "fail";
        }
    }
}
